<!-- 
  ref() 与 reactive() 
    都是叫做组合式API中一种响应式API，可以使用他们来创建响应式的数据

  reactive()
    接受一个值，返回这个值的响应式代理对象

    局限性：
      1. 接受的值，只能是 对象、数组、Map、Set 等复杂类型，不能是原始类型的值。
      2. 不能对其重新赋值，会导致响应式丢失
      3. 不做对其做解构赋值。同样会丢失响应式。

    常见使用的错误：
      1. 通过 reactive 创建一个数组，然后调用接口之后，给数组赋值

  ref 接受非原始类型的值时，内部会借助 reactive() 来处理
      ref(1)            => { value: 1 }
      ref({a: 1, b: 2}) => { value: Proxy{a: 1, b: 2} }

  额外的 ref 解包细节
    解包：无需 .value 的操作，就叫做解包
    1. 将一个ref数据作为一个 reactive 的属性时，访问会自动解包
          const count = ref(1)
          const state = reactive({
            name: '张三',
            num: count
          })
          console.log('count.value', count.value); // 1
          console.log(state.num) // 自动解包，直接得到 1


  总结：ref 与 reactive 的区别：
      1. 两者都是用于创建响应式数据的API.
      2. ref 一般用于基本数据类型，reactive 用于复杂数据类型
      3. ref 使用时需要 .value，reactive 没有 .value
      4. reactive 数据不能整个替换，会丢失响应式
      5. reactive 数据不能做解构，会丢失响应式
      6. 自动解包的细节：当一个 ref数据 作为 reactive 数据的某个属性的值时，当访问该属性会自动解包ref
    
 -->

<template>
  <div>
    <h1>Ref 与 Reactive</h1>

    <p>name: {{ person.name }}</p>
    <p>age: {{ person.age }}</p>
    <button @click="fn1">修改 person.name</button>

    <hr />
    <ul>
      <li v-for="item in list" :key="item.id">{{ item.name }}</li>
    </ul>
  </div>
</template>

<script>
import { onMounted, reactive, ref } from 'vue'

export default {
  setup() {
    const books = reactive([ref('Vue 3 Guide')])
    // 这里需要 .value
    console.log(books[0].value)

    const map = reactive(new Map([['count', ref(0)]]))
    // 这里需要 .value
    console.log(map.get('count').value)

    let person = reactive({
      name: '张三',
      age: 18
    })

    let { name } = person

    console.log('person', person)

    function fn1() {
      // 直接修改是不行的，丢失了响应式
      // person = {
      //   name: '里斯',
      //   age: 18
      // }
      // console.log('name', name) // '张三'
      // person.name = '里斯'
      // console.log('person.name', person.name) // '里斯'
      // console.log('name', name) // '张三'

      console.log('name', name) // '张三'
      name = '里斯'
      console.log('person.name', person.name) // '张三'
      console.log('name', name) // '里斯'
    }

    // let list = reactive([{ id: 1, name: 'Apple' }])
    // console.log('list', list) // 'Proxy'
    // function fetchData() {
    //   setTimeout(() => {
    //     const resp = [
    //       { id: 2, name: 'Banana' },
    //       { id: 3, name: 'Orange' }
    //     ]

    //     list = resp
    //     console.log('list', list)
    //   }, 2000)
    // }

    let list = ref([{ id: 1, name: 'Apple' }])
    function fetchData() {
      setTimeout(() => {
        const resp = [
          { id: 2, name: 'Banana' },
          { id: 3, name: 'Orange' }
        ]

        list.value = resp
      }, 2000)
    }

    const msg = ref(1)
    const message = ref({ a: 1, b: 2 })
    console.log('msg', msg)
    console.log('message', message)

    onMounted(() => {
      fetchData()
    })

    return {
      person,
      fn1,
      list
    }
  }
}
</script>
